package com.ruoyi.web.controller.biz;

import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import com.ruoyi.biz.domain.ChipInfo;
import com.ruoyi.biz.domain.SensorInfo;
import com.ruoyi.common.core.domain.vo.ChartVo;
import com.ruoyi.data.tdengine.domain.Sensor;
import com.ruoyi.data.tdengine.service.SensorService;
import com.ruoyi.biz.service.ISensorInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.biz.service.IChipInfoService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

import javax.annotation.Resource;

/**
 * 芯片管理Controller
 * 
 * @author zhouzhou
 * @date 2021-07-26
 */
@RestController
@RequestMapping("/system/chip")
@Api(tags = "芯片管理")
public class ChipInfoController extends BaseController
{
    @Autowired
    private IChipInfoService chipInfoService;
    @Resource
    private SensorService sensorService;
    @Autowired
    private ISensorInfoService iSensorInfoService;


    /**
     * 判断设备是否有传感器，有就渲染数据
     * @param equipmentId
     * @return
     */
    @GetMapping("/find/{equipmentId}")
    public AjaxResult findCount(@PathVariable Long equipmentId){
        ChipInfo chipInfo = new ChipInfo();
        chipInfo.setEquipmentId(equipmentId);
        List<ChipInfo> chipInfos = chipInfoService.selectChipInfoList(chipInfo);

        AtomicInteger data = new AtomicInteger();
        for (ChipInfo info : chipInfos) {
            SensorInfo sensorInfo = new SensorInfo();
            sensorInfo.setChipId(info.getChipId());
            List<SensorInfo> sensorInfos = iSensorInfoService.selectSensorInfoList(sensorInfo);
            if (sensorInfos.size()>0){
                data.set(1);
                break;
            }
        }
        return AjaxResult.success(data);
    }

    /**
     * 获取全部芯片类型
     * @return
     */
    @GetMapping("/type/all")
    public AjaxResult getAllType(){
        return AjaxResult.success(chipInfoService.selectType());
    }

    @ApiOperation("插入测试数据")
    @GetMapping("/test/data/{data}/{sensorCode}")
    public AjaxResult testData(@PathVariable("data") Double data,@PathVariable("sensorCode") String sensorCode){
        SensorInfo sensorInfo = iSensorInfoService.selectSensorByCode(sensorCode);
        sensorService.insertSensorData(sensorCode,data,sensorInfo.getChipNum());
        return AjaxResult.success();
    }

    @ApiOperation("插入一个月的测试数据")
    @GetMapping("/test/data/batch/{sensorCode}/{maxData}")
    public AjaxResult testBatchData(@PathVariable("sensorCode") String sensorCode,@PathVariable Integer maxData){
        SensorInfo sensorInfo = iSensorInfoService.selectSensorByCode(sensorCode);
        for (int i = 0; i < 30; i++) {
            double random = Math.random()*maxData;
            sensorService.insertSensorBatchData(sensorCode,random,i,sensorInfo.getChipNum());
        }
        return AjaxResult.success();
    }

    /**
     * 获取传感器的列表
     */
    @GetMapping("/getChipInfoList")
    public List<ChipInfo> getChipInfo(){
        return chipInfoService.selectChipInfoList(new ChipInfo());
    }

    /**
     * 获取传感器的列表
     */
    @GetMapping("/getSensorDatas/{chipId}")
    public List<SensorInfo> getSensorDatas(@PathVariable Long chipId){
        SensorInfo sensorInfo = new SensorInfo();
        sensorInfo.setChipId(chipId);
        return iSensorInfoService.selectSensorInfoList(sensorInfo);
    }

    /**
     * 获取图表数据
     * TODO 数据获取还有问题，未解决单一开始/结束时间
     * @return
     */
    @ApiOperation("获取图表数据")
    @GetMapping("/data/Chart")
    public AjaxResult getChart(ChartVo chartVo){
        long startTime = System.currentTimeMillis();
        List<Sensor> sensorList = new CopyOnWriteArrayList<>();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();

        List<String> collect = null;
        //数据收集
        Map<String,List> stringListHashMap = new HashMap<>();
        /**
         * 开始时间与结束时间进行细粒度控制
         * 小于一个小时按分钟
         * 大于一个小时小于一天按小时
         * 大于一天按天
         */
        if (chartVo.getPlanBeginTime()==null && chartVo.getPlanEndTime()==null){
            throw new RuntimeException("请选择时间区域");
        }

        Date planBeginTime = chartVo.getPlanBeginTime();
        Date planEndTime = chartVo.getPlanEndTime();
        //时间差
        long time  = planEndTime.getTime() - planBeginTime.getTime();
        long Day = 1000*60*60*24; //天
        long Hour = 1000*60*60; //时
        long minute = 1000*60*5;//分


        try{
            //只有开始时间、或者只有结束时间，或者开始到结束时间大于1天都按该方法
            if (time>Day || chartVo.getPlanEndTime()==null || chartVo.getPlanBeginTime()== null){
                simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                long endTime = planEndTime.getTime()+ Day;
                chartVo.setPlanEndTime(new Date(endTime));
                sensorList = sensorService.getChart(chartVo.getPlanBeginTime(),chartVo.getPlanEndTime(),chartVo.getSensorCode());
            }else if(time>Hour && time <=Day){
                simpleDateFormat = new SimpleDateFormat("HH:mm");
                long endTime = planEndTime.getTime()+ Hour;
                chartVo.setPlanEndTime(new Date(endTime));
                sensorList = sensorService.getChartByHour(chartVo.getPlanBeginTime(),chartVo.getPlanEndTime(),chartVo.getSensorCode());
            }else {
                simpleDateFormat = new SimpleDateFormat("HH:mm");
                long endTime = planEndTime.getTime()+minute;
                chartVo.setPlanEndTime(new Date(endTime));
                sensorList = sensorService.getChartMinute(chartVo.getPlanBeginTime(),chartVo.getPlanEndTime(),chartVo.getSensorCode());
            }
        }catch (Exception e){
            throw new RuntimeException("该传感器无数据");
        }



        SimpleDateFormat finalSimpleDateFormat = simpleDateFormat;
        collect = sensorList.stream().map(item -> {
            Timestamp ts = item.getTs();
            return finalSimpleDateFormat.format(ts);
        }).collect(Collectors.toList());

        /**
         * 依据精度进行处理 78.439  精度 0.1   78.4
         */
        SensorInfo sensorInfo = iSensorInfoService.selectSensorByCode(chartVo.getSensorCode());
        String rule = getNumberDecimalDigits(sensorInfo.getAccuracy());
        logger.debug("处理规则：{}",rule);
        List<Double> doubles = sensorList.stream().map(item->{
            DecimalFormat df = new DecimalFormat(rule);
            String str = df.format(item.getValue());
           return Double.valueOf(str);
        }).collect(Collectors.toList());
        stringListHashMap.put("ts",collect);
        stringListHashMap.put("value",doubles);
        long endTime = System.currentTimeMillis();
        logger.debug("程序运行时间:{}" ,(endTime - startTime) + "ms");
        return AjaxResult.success(stringListHashMap);
    }

    /**
     * 计算DecimalFormat转码规则的算法
     * @param number
     * @return
     */
    public static String getNumberDecimalDigits(double number) {
        StringBuilder str = new StringBuilder("#0.");
        if (number == (long)number) {
            return str.toString();
        }
        int i = 0;
        while (true){
            i++;
            str.append("0");
            if (number * Math.pow(10, i) % 1 == 0) {
                return str.toString();
            }
        }
    }



    /**
     * 置顶
     */
    @GetMapping("/showTop/{chipId}")
    public AjaxResult Top(@PathVariable("chipId") Long chipId){
        ChipInfo chipInfo = chipInfoService.selectChipInfoById(chipId);
        Integer maxSort = chipInfoService.findMaxSort();
        chipInfo.setSort(maxSort+1);
        chipInfoService.updateChipInfo(chipInfo);
        return AjaxResult.success();
    }

    /**
     * 查询芯片管理列表
     */
    @PreAuthorize("@ss.hasPermi('system:chip:list')")
    @GetMapping("/list")
    public TableDataInfo list(ChipInfo chipInfo)
    {
        startPage();
        logger.debug("芯片对象:{}",chipInfo);
        List<ChipInfo> list = chipInfoService.selectChipInfoList(chipInfo);
        return getDataTable(list);
    }

    /**
     * 导出芯片管理列表
     */
    @PreAuthorize("@ss.hasPermi('system:chip:export')")
    @Log(title = "芯片管理", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(ChipInfo chipInfo)
    {

        List<ChipInfo> list = chipInfoService.selectChipInfoList(chipInfo);
        ExcelUtil<ChipInfo> util = new ExcelUtil<ChipInfo>(ChipInfo.class);
        return util.exportExcel(list, "chip");
    }

    /**
     * 获取芯片管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:chip:query')")
    @GetMapping(value = "/{chipId}")
    public AjaxResult getInfo(@PathVariable("chipId") Long chipId)
    {
        return AjaxResult.success(chipInfoService.selectChipInfoById(chipId));
    }

    /**
     * 新增芯片管理
     */
    @PreAuthorize("@ss.hasPermi('system:chip:add')")
    @Log(title = "芯片管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ChipInfo chipInfo)
    {

        return toAjax(chipInfoService.insertChipInfo(chipInfo));
    }

    /**
     * 修改芯片管理
     */
    @PreAuthorize("@ss.hasPermi('system:chip:edit')")
    @Log(title = "芯片管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ChipInfo chipInfo)
    {
        return toAjax(chipInfoService.updateChipInfo(chipInfo));
    }

    /**
     * 删除芯片管理
     */
    @PreAuthorize("@ss.hasPermi('system:chip:remove')")
    @Log(title = "芯片管理", businessType = BusinessType.DELETE)
	@DeleteMapping("/{chipIds}")
    public AjaxResult remove(@PathVariable Long[] chipIds)
    {
        return toAjax(chipInfoService.deleteChipInfoByIds(chipIds));
    }
}
